
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>mybatis的缓存机制 - 学习卡片</title>
      <style>
        body { font-family: sans-serif; background-color: #f0f8ff; color: #333; display: flex; flex-direction: column; align-items: center; padding: 50px 20px; }
        .header h1 { font-size: 32px; }
        .grid-container { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; width: 100%; max-width: 1200px; }
        .card-container { perspective: 1200px; cursor: pointer; height: 250px; }
        .card { width: 100%; height: 100%; position: relative; transform-style: preserve-3d; transition: transform 0.7s; border-radius: 16px; box-shadow: 0 4px 16px rgba(0,0,0,0.08); }
        .card-container.flipped .card { transform: rotateY(180deg); }
        .card-face { position: absolute; width: 100%; height: 100%; backface-visibility: hidden; display: flex; flex-direction: column; box-sizing: border-box; border-radius: 16px; background-color: #fff; padding: 24px; }
        .card-back { background-color: #f0fff4; transform: rotateY(180deg); justify-content: space-between; }
        .card-category { font-size: 14px; color: #0052d9; margin-bottom: 8px; font-weight: 500; }
        .card-question { font-size: 20px; font-weight: 500; flex-grow: 1; display: flex; align-items: center; justify-content: center; text-align: center; }
        .card-answer-wrapper { flex-grow: 1; overflow-y: auto; }
        .card-answer { font-size: 15px; line-height: 1.7; }
        .card-footer { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 16px; margin-top: 16px; }
        .card-source { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 12px; margin-top: 12px; }
      </style>
    </head>
    <body>
      <div class="header">
        <h1>mybatis的缓存机制 - 学习卡片</h1>
      </div>
      <div class="grid-container">
        
    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">理论</div>
          <div class="card-question">MyBatis中的两种核心缓存类型是什么？它们的作用域有何不同？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">理论</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">MyBatis的核心缓存分为一级缓存和二级缓存。一级缓存是基于SqlSession的，其生命周期与SqlSession相同。二级缓存是基于Mapper（或SqlSessionFactory）的，可以跨多个SqlSession共享数据。</div>
          </div>
          <div class="card-source">来源: 缓存类型</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">请描述MyBatis一级缓存的工作原理。</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">在同一个SqlSession中，当执行查询时，MyBatis会首先检查一级缓存中是否存在相同的查询结果。如果存在，则直接从缓存中获取结果，而不执行实际的数据库查询。如果不存在，则执行数据库查询，并将查询结果存入缓存中。</div>
          </div>
          <div class="card-source">来源: 一级缓存 - 工作原理</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">特性</div>
          <div class="card-question">在什么情况下MyBatis的一级缓存会自动被清空？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">特性</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">当执行数据更新操作（如插入、更新、删除）后，MyBatis会清空一级缓存，以避免产生脏数据。</div>
          </div>
          <div class="card-source">来源: 一级缓存 - 注意事项</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">理论</div>
          <div class="card-question">MyBatis的二级缓存与一级缓存相比，其主要优势和作用范围是什么？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">理论</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">二级缓存的主要优势是可以跨SqlSession共享缓存数据，从而减少多个SqlSession对相同数据的重复查询。它的作用范围是SqlSessionFactory，即由同一个SqlSessionFactory创建的多个SqlSession可以共享同一个二级缓存。</div>
          </div>
          <div class="card-source">来源: 二级缓存</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">如何为MyBatis开启并配置二级缓存？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">首先，需要在MyBatis全局配置文件中设置 `cacheEnabled` 为 `true`。然后，在需要开启二级缓存的Mapper XML文件中，使用 `<cache>` 或 `<cache-ref>` 元素进行配置。对于具体的查询语句，可以通过 `useCache="true"` 属性来控制是否使用二级缓存。</div>
          </div>
          <div class="card-source">来源: 二级缓存 - 配置方式, 示例</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">MyBatis的二级缓存是基于什么进行隔离和管理的？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">二级缓存是基于命名空间（Namespace）进行管理的。不同的Mapper接口或XML映射文件拥有不同的命名空间，每个命名空间都拥有自己独立的二级缓存。</div>
          </div>
          <div class="card-source">来源: 二级缓存 - 工作原理</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">模式</div>
          <div class="card-question">文档中提到了哪四种缓存清理策略？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">模式</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">文档中提到的四种缓存清理策略是：1. 基于时间的清理策略（定期清理）；2. 基于数量的清理策略（达到阈值时清理）；3. 基于引用的清理策略（长时间未被访问时清理）；4. 基于事件的清理策略（数据库数据变化时通知清理）。</div>
          </div>
          <div class="card-source">来源: 缓存的清理策略</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">如果想在MyBatis中使用自定义的缓存实现（例如Redis缓存），应该怎么做？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">需要创建一个自定义的缓存实现类，并实现MyBatis提供的 `org.apache.ibatis.cache.Cache` 接口。然后，在MyBatis的配置中，将这个自定义的缓存实现类指定为缓存对象，例如通过SqlSessionFactoryBean的`setCache`方法进行注入。</div>
          </div>
          <div class="card-source">来源: 缓存的扩展 - 自定义缓存实现</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">特性</div>
          <div class="card-question">一级缓存是默认开启的吗？它在不同的SqlSession实例之间是否可以共享？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">特性</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">是的，一级缓存是默认开启的，并且不可关闭。但是，一级缓存是和SqlSession绑定的，因此在不同的SqlSession实例之间无法共享缓存数据。</div>
          </div>
          <div class="card-source">来源: 一级缓存 - 注意事项</div>
        </div>
      </div>
    </div>

      </div>
    </body>
    </html>
